package com.universest.swordholder.task

import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flow



class NeedPrepareTask<A, B>(
    name: String = "",
    // 准备阶段的最大进度值，默认为1
    private val prepareMaxProgress: Int = 1,
    // 主任务的最大进度值，默认为99
    private val taskMaxProgress: Int = 99,
    // 用于创建实际任务的挂起函数
    private val prepareTask: AbstractTask<A, AbstractTask<A,B>>
) : AbstractTask<A, B>(name), TaskGroup {

    // 存储已准备好的任务实例
    private var preparedTask: AbstractTask<A, B>? = null

    private val _prepared = MutableStateFlow(false)

    override suspend fun call(param: A): B {
        _prepared.emit(false)
        val task = prepareTask.execute(param).getOrThrow()
        checkCancelled()
        preparedTask = task
        _prepared.emit(true)
        checkCancelled()
        val result = task.execute(param)
        checkCancelled()
        return result.getOrThrow()
    }

    // 实现progress属性，返回一个Flow表示任务的整体进度
    override val progress: Flow<Pair<Int, Int>> = flow {
        prepareTask.progress.collect {
            emit((it.first * prepareMaxProgress/it.second.toFloat()).toInt() to (taskMaxProgress + prepareMaxProgress))
        }
        combine(_prepared,end) { first, second ->
            first || second
        }
        .firstOrNull { it }
        preparedTask?.progress?.collect {
            emit((it.first * taskMaxProgress/it.second.toFloat()+prepareMaxProgress).toInt() to (taskMaxProgress + prepareMaxProgress))
        }
        preparedTask?.end?.collect {
            emit((taskMaxProgress + prepareMaxProgress) to (taskMaxProgress + prepareMaxProgress))
        }
    }

    // 实现message属性，返回一个Flow表示任务的消息
    override val message: Flow<String> = flow {
        prepareTask.message.collect {
            emit(it)
        }
        combine(_prepared,end) { first, second ->
            first || second
        }
        .firstOrNull { it }
        if(!isEnd()) {
            preparedTask?.message?.collect {
                emit(it)
            }
        }
    }

    // 实现currentRunningTask属性，返回当前正在运行的任务
    override val currentRunningTask: AbstractTask<*,*>
        get() {
            val task = preparedTask
            return when (task) {
                null -> this.prepareTask              // 如果没有准备好的任务，则返回自己
                is TaskGroup -> task.currentRunningTask  // 如果是TaskGroup，则递归查找
                else -> task              // 否则返回准备好的任务
            }
        }

    override val tasks: List<AbstractTask<*,*>>
        get() {
            val task = preparedTask
            if (task == null) return listOf(prepareTask)
            return listOf(prepareTask, task)
        }
}
